package com.znufe.exam.controller.admin;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

import com.github.pagehelper.PageInfo;
import com.znufe.exam.base.BaseApiController;
import com.znufe.exam.configuration.config.annotation.Log;
import com.znufe.exam.configuration.config.enums.BusinessType;
import com.znufe.exam.domain.ExamPaper;
import com.znufe.exam.domain.subcourse.SubCourseResponseObject;
import com.znufe.exam.domain.SubCourseExamPaper;
import com.znufe.exam.service.ExamPaperService;
import com.znufe.exam.service.SubCourseExamPaperService;
import com.znufe.exam.utility.FileHandleUtil;
import com.znufe.exam.utility.PageInfoHelper;
import com.znufe.exam.utility.VideoUtil;
import com.znufe.exam.viewmodel.admin.subCourse.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.znufe.exam.domain.SubCourse;
import com.znufe.exam.service.SubCourseService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

import com.znufe.exam.base.RestResponse;
import com.znufe.exam.base.SystemCode;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

/**   
 * 
 * @Description:  课程表接口层
 * @Author:       gong   
 * @CreateDate:   Course
 * @Version:      V1.0
 *    
 */
@Api(description = "子课程信息表",value="子课程信息表" )
@RestController("AdminSubCourseController")
@RequestMapping("/api/admin/subCourse")
public class SubCourseController extends BaseApiController {

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	public SubCourseService subCourseService;
	@Autowired
	public SubCourseExamPaperService subCourseExamPaperService;
	@Autowired
    public ExamPaperService examPaperService;

	/**
	 * @explain 管理端：根据视频ID查询视频
	 * @param   id
	 * @return  subCourse
	 * @author  gong
	 */
    @PreAuthorize("@ss.hasPermi('courses:videos:query')")
	@RequestMapping(value = "/select/{id}",method = RequestMethod.GET)
	@ApiOperation(value = "获取视频信息", notes = "根据视频ID获取视频信息")
	@ApiImplicitParam(paramType="path", name = "id", value = "视频id", required = true, dataType = "int")
	public RestResponse<SubCourse> getSubCourseById(@PathVariable("id") Integer id){
		try {
			SubCourse subCourse=subCourseService.selectByPrimaryKey(id);
			if (subCourse != null) {
				return RestResponse.ok(subCourse);
			} else {
				logger.error("查询子课程表执行失败："+subCourse.toString());
				return RestResponse.fail(SystemCode.NoDataExist.getCode(),SystemCode.NoDataExist.getMessage());
			}
		} catch (Exception e) {
			logger.error("查询子课程表执行异常："+e.getMessage());
			return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
		}
	}

    @PreAuthorize("@ss.hasAnyPermi('courses:videos:add,courses:videos:update')")
    @Log(title = "视频管理", businessType = BusinessType.EDIT)
	@RequestMapping(value = "/edit",method = RequestMethod.POST)
    @ApiOperation(value = "编辑视频信息（新增/更新）",
                  notes = "新增/更新视频信息（更新请传入视频id）")
    public RestResponse<SubCourse> edit(@RequestBody @Valid SubCourseCreateVm createVm){
        if(createVm.getId() == null){
            SubCourse existSubCourse = subCourseService.selectSubCourseByName(createVm.getSubCourseName());
            if(null != existSubCourse){
                return new RestResponse<>(421,"视频已存在，请更改视频名称");
            }
        }
        SubCourse newSubCourse = modelMapper.map(createVm,SubCourse.class);
        if(createVm.getId() == null){
            newSubCourse.setIsDeleted(0);
            newSubCourse.setStatus(0);
            newSubCourse.setGmtCreate(new Date());
            subCourseService.insertSelective(newSubCourse);
        }else {
            newSubCourse.setGmtModified(new Date());
            subCourseService.updateByPrimaryKeySelective(newSubCourse);
        }
        return RestResponse.ok(newSubCourse);
    }

    @PreAuthorize("@ss.hasPermi('courses:videos:bind')")
    @Log(title = "视频管理", businessType = BusinessType.OTHER)
    @PostMapping("/bindExamPaper")
    @ApiOperation(value = "视频绑定试卷",notes = "传入试卷ID数组")
    public RestResponse bindExamPaper(@RequestBody SubCourseBindPaperRequestVm requestVm){
        subCourseExamPaperService.deleteBySubCourseId(requestVm.getId());
	    try{
            List<Integer> examPaperList = requestVm.getExamPaperList();
            //判断是否有重复
            long count = examPaperList.stream().distinct().count();
            if (examPaperList.size() != count){
                return RestResponse.fail(SystemCode.DuplicateElement.getCode(),SystemCode.DuplicateElement.getMessage());
            }
            for (int i = 0;i<examPaperList.size();i++){
                int examPaperId = examPaperList.get(i);
                SubCourseExamPaper scep = new SubCourseExamPaper();
                scep.setSubCourseId(requestVm.getId());
                scep.setExamPaperId(examPaperId);
                scep.setGmtCreate(new Date());
                int reg = subCourseExamPaperService.insertSelective(scep);
                if(reg <= 0){
                    return RestResponse.fail(SystemCode.InsertDataFail.getCode(),SystemCode.InsertDataFail.getMessage());
                }
            }
            return RestResponse.ok("绑定成功");
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @PreAuthorize("@ss.hasPermi('courses:videos:list')")
    @RequestMapping(value = "/subCoursePage",method = RequestMethod.POST)
    @ApiOperation(value = "管理端：分页显示课程信息+搜索（无参数查找/按视频名称查找/按讲师姓名查找）",
                  notes = "查询课程信息")
    @ApiImplicitParam(paramType="body", name = "requestVm", value = "项目类别+课程名+课程分级+分页信息", dataType = "SubCoursePageRequestVm",required = true)
    public RestResponse<PageInfo<SubCoursePageResponseVm>> subCoursePage(@RequestBody SubCoursePageRequestVm requestVm){
	    try{
	        requestVm.setSubCourseName(requestVm.getSubCourseName().trim());
	        String lecturerName = requestVm.getLecturerName().trim();
	        requestVm.setLecturerName(lecturerName);
            PageInfo<SubCourseResponseObject> pageInfo = subCourseService.subCoursePage(requestVm);
            PageInfo<SubCoursePageResponseVm> page = PageInfoHelper.copyMap(pageInfo,d->SubCoursePageResponseVm.from(d));
            return RestResponse.ok(page);
        }catch (Exception e){
            return RestResponse.fail(SystemCode.NoDataExist.getCode(), SystemCode.NoDataExist.getMessage());
        }
    }

    @PreAuthorize("@ss.hasPermi('courses:videos:update')")
    @Log(title = "视频管理", businessType = BusinessType.UPDATE)
    @RequestMapping(value = "/changeStatus/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：改变视频状态（禁用/启用）")
    public RestResponse<Integer> changeStatus(@PathVariable Integer id){
	    try {
            SubCourse subCourse = subCourseService.selectByPrimaryKey(id);
            if (subCourse != null) {
                Integer newStatus = subCourse.getStatus() == 1 ? 0 : 1;
                subCourse.setStatus(newStatus);
                subCourse.setGmtModified(new Date());
                int reg = subCourseService.updateByPrimaryKeySelective(subCourse);
                if (reg > 0) {
                    return RestResponse.ok(newStatus);
                } else {
                    return RestResponse.fail(SystemCode.UpdateDataFail.getCode(), SystemCode.UpdateDataFail.getMessage());
                }
            } else {
                return RestResponse.fail(SystemCode.NoDataExist.getCode(), SystemCode.NoDataExist.getMessage());
            }
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @PreAuthorize("@ss.hasPermi('courses:videos:delete')")
    @Log(title = "视频管理", businessType = BusinessType.DELETE)
    @RequestMapping(value = "/delete/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：通过ID删除视频")
    public RestResponse<Integer> delete(@PathVariable Integer id){
	    try{
            SubCourse subCourse = subCourseService.selectByPrimaryKey(id);
            if(subCourse != null){
                subCourse.setIsDeleted(1);
                subCourseService.updateByIdFilter(subCourse);
                return RestResponse.ok(1);
            }else {
                return RestResponse.fail(SystemCode.DeleteDataFail.getCode(),SystemCode.DeleteDataFail.getMessage());
            }
        }catch (Exception e){
	        return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @RequestMapping(value = "/getAllVideo",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：获取所有课程",notes = "用于新建课程时添加视频")
    public RestResponse<List<SubCourse>> getAllVideo(){
	    try {
            List<SubCourse> subCourseList = subCourseService.getAllVideo();
            return RestResponse.ok(subCourseList);
        }catch (Exception e){
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @PostMapping(value = "/videoUpload")
    @ApiOperation(value = "管理端：上传视频", notes = "返回数据库存放地址（字符串），随表单一起提交")
    public RestResponse<VideoResponseVm> videoUpload(MultipartFile uploadFile){
	    boolean flag = false;
	    VideoResponseVm responseVm = new VideoResponseVm();
        try{
            if (uploadFile.isEmpty()){
                return RestResponse.fail(SystemCode.FileEmptyError.getCode(),SystemCode.FileEmptyError.getMessage());
            }
            String originalFileName = uploadFile.getOriginalFilename();
            if(VideoUtil.checkVideoSize(uploadFile)){
                if (VideoUtil.checkVideoType(originalFileName)){
                    flag = true;
                }else {
                    return RestResponse.fail(SystemCode.FileFormatError.getCode(),SystemCode.FileFormatError.getMessage());
                }
            }else {
                return RestResponse.fail(SystemCode.FileSizeError.getCode(),SystemCode.FileSizeError.getMessage());
            }
            if(flag == true){
                String newName = UUID.randomUUID().toString() + originalFileName.substring(originalFileName.lastIndexOf("."));
                String filePath = FileHandleUtil.upload(uploadFile.getInputStream(), "video/", newName);
                responseVm.setVideoPath(filePath);
                File file = VideoUtil.multipartFileToFile(uploadFile);
                responseVm.setVideoLength(VideoUtil.getVideoDuration(file));
                File f = new File(file.toURI());
                f.delete();
                return RestResponse.ok(responseVm);
            }else {
                return RestResponse.fail(400,"视频上传失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            return RestResponse.fail(SystemCode.InnerError.getCode(),SystemCode.InnerError.getMessage());
        }
    }

    @RequestMapping(value = "/scanVideo",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：获取指定目录视频文件")
    public RestResponse<List<String>> scanVideo(){
	    File file = new File("static/upload/self");
	    if (!file.exists()){
	        return RestResponse.fail(SystemCode.NoVideoExist.getCode(),SystemCode.NoVideoExist.getMessage());
        }
        //获取文件夹里所有文件
	    File[] arrFiles = file.listFiles();
	    //存储最后返回的文件名
	    List<String> fileList = new ArrayList<>();
	    for (int i = 0;i < arrFiles.length;i++){
	        File tempFile = arrFiles[i];
	        if (VideoUtil.checkVideoType(tempFile.getName())){
	            String fileName = tempFile.getName();
	            fileList.add(fileName);
            }
        }
        return RestResponse.ok(fileList);
    }

    @RequestMapping(value = "/videoInsert",method = RequestMethod.POST)
    @ApiOperation(value = "管理端：视频已手动复制时，返回视频信息")
    public RestResponse<VideoResponseVm> videoInsert(@RequestBody VideoInsertVm insertVm){
	    File file = new File("static/upload/self/"+insertVm.getVideoName());
        VideoResponseVm responseVm = new VideoResponseVm();
        responseVm.setVideoLength(VideoUtil.getVideoDurationNotDelete(file));
        try{
            String urlName = URLEncoder.encode(insertVm.getVideoName(),"utf-8");
            responseVm.setVideoPath("/upload/self/"+urlName);
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return RestResponse.ok(responseVm);
    }

    @RequestMapping(value = "/getBindExamPaper/{id}",method = RequestMethod.GET)
    @ApiOperation(value = "管理端：获取视频绑定的所有试卷")
    public RestResponse<List<ExamPaper>> getBindExamPaper(@PathVariable("id") Integer id){
	    List<Integer> examPaperId = subCourseExamPaperService.getAllExamPaperId(id);
	    if (examPaperId.size() == 0){
            return RestResponse.ok(Collections.emptyList());
        }else {
	        List<ExamPaper> paperList = examPaperService.getAllExamPaperListById(examPaperId);
            return RestResponse.ok(paperList);
        }
    }
}